package com.ct.musicserver.service.impl;

import com.ct.musicserver.common.errorcode.ServiceErrorCodeConstants;
import com.ct.musicserver.common.exception.ServiceException;
import com.ct.musicserver.common.utils.Constant;
import com.ct.musicserver.controller.param.DelMusicParam;
import com.ct.musicserver.controller.result.UserLoginResult;
import com.ct.musicserver.dao.dataobject.LoveMusicDO;
import com.ct.musicserver.dao.dataobject.MusicDO;
import com.ct.musicserver.dao.mapper.LoveMusicMapper;
import com.ct.musicserver.dao.mapper.MusicMapper;
import com.ct.musicserver.service.MusicService;
import com.ct.musicserver.service.dto.FindMusicDTO;
import com.ct.musicserver.service.enums.MusicStatusEnum;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MusicServiceImpl implements MusicService {

    @Value("${music.local.path}")
    private String localPath;
    @Autowired
    private HttpSession session;
    @Autowired
    private MusicMapper musicMapper;
    @Autowired
    private LoveMusicMapper loveMusicMapper;

    @Override
    @Transactional(rollbackFor = Exception.class) // 涉及多表
    public void upload(String singer, MultipartFile file) {

        if (!StringUtils.hasText(singer)
                || null == file
                || file.isEmpty()) {
            throw new ServiceException(ServiceErrorCodeConstants.SINGER_OR_FILE_IS_EMPTY);
        }

        // 创建索引
        String filename = file.getOriginalFilename();
        assert filename != null;
        int index = filename.lastIndexOf(".");
        String title = filename.substring(0, index);
        UserLoginResult userInfo = (UserLoginResult) session.getAttribute(Constant.USERINFO_SESSION_KEY);
        Long userid = userInfo.getId();

        // 检查是否已经有此歌曲
        MusicDO musicDO = musicMapper.selectBySingerAndFile(singer, title);
        if (null != musicDO) {
                if (MusicStatusEnum.RUNNING.getCode().equals(musicDO.getStatus())) {
                    throw new ServiceException(ServiceErrorCodeConstants.MUSIC_IS_EXIST);
                } else {
                    musicMapper.uploadMusicById(musicDO.getId());

                    LoveMusicDO loveMusicDO = new LoveMusicDO();
                    loveMusicDO.setUserId(userid);
                    loveMusicDO.setMusicId(musicDO.getId());
                    loveMusicMapper.insert(loveMusicDO);
                    return;
                }
        }

        // 上传歌曲
        // 创建目录
        File dir = new File(localPath);

        if (!dir.exists()) {
            dir.mkdirs();
        }

        try {
            file.transferTo(new File(localPath + "/" + filename));
        } catch (IOException e) {
            throw new ServiceException(ServiceErrorCodeConstants.MUSIC_UPLOAD_ERROR);
        }

        // 数据准备
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String time = dateFormat.format(new Date());
        String url = "/music/get?path=" + title;

        musicDO = new MusicDO();
        musicDO.setSinger(singer);
        musicDO.setStatus(MusicStatusEnum.RUNNING.getCode());
        musicDO.setTime(time);
        musicDO.setTitle(title);
        musicDO.setUrl(url);
        musicDO.setUserid(userid);
        musicMapper.insert(musicDO);

        LoveMusicDO loveMusicDO = new LoveMusicDO();
        loveMusicDO.setUserId(userid);
        loveMusicDO.setMusicId(musicDO.getId());
        loveMusicMapper.insert(loveMusicDO);
    }

    @Override
    public ResponseEntity<byte[]> get(String path) {
        File file = new File(localPath + "/" + path);
        byte[] a = null;
        try {
            // Files.readAllBytes() 在遇到空文件时也会返回
            // 一个长度为 0 的数组（即 new byte[0]）
            a = Files.readAllBytes(file.toPath());
            if(a.length == 0) {
                return ResponseEntity.badRequest().build();
            }
            return ResponseEntity.ok(a);
        } catch (IOException e) {
            throw new ServiceException(ServiceErrorCodeConstants.FILE_READ_ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 涉及多表
    public void delMusic(DelMusicParam param) {
        MusicDO musicDO  = musicMapper.selectById(param.getId());
        if (null == musicDO
                || MusicStatusEnum.DISABLE.getCode().equals(musicDO.getStatus())) {
            throw new ServiceException(ServiceErrorCodeConstants.MUSIC_INFO_IS_EMPTY);
        }

        // 删除 music 中的
        // 软删除
        musicMapper.deleteMusicById(param.getId());

        // 删除 lovemusic 中的
        UserLoginResult userInfo = (UserLoginResult) session.getAttribute(Constant.USERINFO_SESSION_KEY);
        Long userid = userInfo.getId();
        loveMusicMapper.deleteByMusicIdAndUserId(musicDO.getId(), userid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 涉及多表
    public void delSelById(List<Long> ids) {
        if (null == ids
                || ids.isEmpty()) {
            throw new ServiceException(ServiceErrorCodeConstants.MUSIC_INFO_IS_EMPTY);
        }

        ids.stream()
                .distinct()
                .forEach(id -> {
                    MusicDO musicDO = musicMapper.selectById(id);
                    if (musicDO == null || MusicStatusEnum.DISABLE.getCode().equals(musicDO.getStatus())) {
                        throw new ServiceException(ServiceErrorCodeConstants.MUSIC_INFO_HAS_EMPTY);
                    }

                    musicMapper.deleteMusicById(id);
                    UserLoginResult userInfo = (UserLoginResult) session.getAttribute(Constant.USERINFO_SESSION_KEY);
                    Long userid = userInfo.getId();
                    loveMusicMapper.deleteByMusicIdAndUserId(id, userid);
                });
    }

    @Override
    public List<FindMusicDTO> findMusic(String musicName) {

        List<MusicDO> musicDOList = new ArrayList<>();

        if (!StringUtils.hasText(musicName)) {
            musicDOList = musicMapper.selectMusic();
        } else {
            musicDOList = musicMapper.selectByMusicName(musicName);
        }
        List<FindMusicDTO> findMusicDTOList = musicDOList.stream()
                .map(musicDO -> {
                    FindMusicDTO findMusicDTO = new FindMusicDTO();
                    findMusicDTO.setId(musicDO.getId());
                    findMusicDTO.setSinger(musicDO.getSinger());
                    findMusicDTO.setTime(musicDO.getTime());
                    findMusicDTO.setTitle(musicDO.getTitle());
                    findMusicDTO.setUrl(musicDO.getUrl());
                    findMusicDTO.setUserid(musicDO.getUserid());
                    return findMusicDTO;
                }).collect(Collectors.toList());
        return findMusicDTOList;
    }


}
